﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure.Diagnostics.Management;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using System.IO;

namespace MyLib
{
    public class MyDiagnosticManager
    {
        private MyDiagnosticManager()
        { 
        }

        private DeploymentDiagnosticManager ddm 
        {
            get; 
            set;
        }


        public void CollectTrace()
        {

            #region Iterate Roles/Instances
            //iterate Roles
            var roles = ddm.GetRoleNames();

            foreach (var role in roles)
            {
                var instances = ddm.GetRoleInstanceDiagnosticManagersForRole(role);
                //iterate Instances and set Diag Config
                foreach (var diagMonitor in instances)
                {
                    var dc = diagMonitor.GetCurrentConfiguration();
                    dc.Logs.BufferQuotaInMB = 100;
                    dc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
                    diagMonitor.SetCurrentConfiguration(dc);
                }
            }
            #endregion
        }


        //Switch on the CPU collection for all Roles and for All instances
        //http://msdn.microsoft.com/en-us/library/windowsazure/gg433015.aspx
        //http://msdn.microsoft.com/en-us/library/windowsazure/gg433049.aspx
        //
        //Performance counters available for Windows Azure
        //http://msdn.microsoft.com/en-us/library/windowsazure/hh411520.aspx
        public void CollectCPU()
        {
            string myCounter = @"\Processor(_Total)\% Processor Time";

            AddPerformanceCounter(myCounter);
        }

        public void AddPerformanceCounter(string performanceCounter)
        {
            var roles = ddm.GetRoleNames();

            var counter = new PerformanceCounterConfiguration();
            counter.CounterSpecifier = performanceCounter;
            counter.SampleRate = TimeSpan.FromSeconds(5);

            int i = 0;
            foreach (var role in roles)
            {
                var instances = ddm.GetRoleInstanceDiagnosticManagersForRole(role);
                foreach (var diagMonitor in instances)
                {
                    i++;
                    var dc = diagMonitor.GetCurrentConfiguration();
                    dc.PerformanceCounters.BufferQuotaInMB = 100;
                    dc.PerformanceCounters.DataSources.Add(counter);
                    dc.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
                    diagMonitor.SetCurrentConfiguration(dc);
                }
            }
        }

        public void ActivateCustomLog()
        {

            #region configure custom log
            var res = RoleEnvironment.GetLocalResource("MyLogs");
            var myDir = new DirectoryConfiguration();
            myDir.Container = "wad-mylogs-container";
            myDir.DirectoryQuotaInMB = res.MaximumSizeInMegabytes;
            myDir.Path = res.RootPath;
            #endregion

            #region iterate roles/instances
            var roles = ddm.GetRoleNames();

            int i = 0;
            foreach (var role in roles)
            {
                var instances = ddm.GetRoleInstanceDiagnosticManagersForRole(role);
                foreach (var diagMonitor in instances)
                {
                    i++;
                    var dc = diagMonitor.GetCurrentConfiguration();

                    dc.Directories.DataSources.Add(myDir);
                    dc.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);

                    diagMonitor.SetCurrentConfiguration(dc);
                }
            }

            #endregion

        }

        public void DoCustomLog()
        {
            var res = RoleEnvironment.GetLocalResource("MyLogs");
            string filename = string.Format(@"{0}\logfile_{1}.txt", res.RootPath, DateTime.Now.Ticks);
            var file = File.CreateText(filename);
            file.WriteLine("My custom file " + DateTime.Now.ToString());
            file.Close();

        }

        //restore default configuration for all Roles and for All instances
        public void RestoreDefaultConfig()
        {
            var roles = ddm.GetRoleNames();

            var dc = DiagnosticMonitor.GetDefaultInitialConfiguration();

            int i = 0;
            foreach (var role in roles)
            {
                var instances = ddm.GetRoleInstanceDiagnosticManagersForRole(role);
                foreach (var diagMonitor in instances)
                {
                    i++;
                    diagMonitor.SetCurrentConfiguration(dc);
                }
            }
        }

        //activate trace for all Roles and for All instances
        public void ActivateTraceDemo()
        {

            #region Iterate Roles/Instances
            //iterate Roles
            var roles = ddm.GetRoleNames();

            foreach (var role in roles)
            {
                var instances = ddm.GetRoleInstanceDiagnosticManagersForRole(role);
                //iterate Instances and set Diag Config
                foreach (var diagMonitor in instances)
                {
                    var dc = diagMonitor.GetCurrentConfiguration();
                    dc.Logs.BufferQuotaInMB = 100;
                    dc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
                    diagMonitor.SetCurrentConfiguration(dc);
                }
            }
            #endregion
        }


        public string GetDiagnosticInfo()
        {

            string s = "";
            StringBuilder sb = new StringBuilder();

            var roles = ddm.GetRoleNames();

            int i = 0;
            foreach (var role in roles)
            {
                i++;
            }

            sb.AppendLine("<h2>Amount of Roles is " + i.ToString() + "</h2>");

            foreach (var role in roles)
            {
                sb.AppendLine("<h1>Role " + role + "</h1>");
                var obj = ddm.GetRoleInstanceDiagnosticManagersForRole(role);



                int j = 0;
                foreach (var dm in obj)
                {
                    j++;
                }
                sb.AppendLine("<h2>Amount of Instances is " + j.ToString() + "</h2>");

                foreach (var dm in obj)
                {
                    sb.AppendLine("<h2>RoleInstanceId " + dm.RoleInstanceId + "</h2>");
                    var dc = dm.GetCurrentConfiguration();
                    sb.AppendLine(MyDiagnosticManager.getInfoDiagnosticMonitorConfiguration(dc));
                }
            }

            s = sb.ToString();

            return s;

        }
 
        static public MyDiagnosticManager GetMyDiagnosticManager(string StorageName, string StorageKey, string DeploymentID)
        {
            var myddm = new MyDiagnosticManager();
            var storageCredentialsAccountAndKey = new StorageCredentialsAccountAndKey(StorageName, StorageKey);
            CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(storageCredentialsAccountAndKey, true);
            var obj = new DeploymentDiagnosticManager(cloudStorageAccount, DeploymentID);
            myddm.ddm = obj;
            return myddm;
        }

        public static string getInfoDiagnosticMonitorConfiguration(DiagnosticMonitorConfiguration dc)
        {
            string s;

            if (dc == null)
            {
                return "<h2>DiagnosticMonitorConfiguration is NULL</h2>";
            }

            string sTemp;

            var sb = new System.Text.StringBuilder();

            sb.AppendLine(string.Format(@"ConfigurationChangePollInterval.TotalSeconds={0}<br/>", dc.ConfigurationChangePollInterval.TotalSeconds));
            sb.AppendLine(string.Format(@"OverallQuotaInMB={0}<br/>", dc.OverallQuotaInMB));


            sb.AppendLine("<strong>DiagnosticInfrastructureLogs</strong><br/>");
            sb.AppendLine(string.Format(@"DiagnosticInfrastructureLogs.BufferQuotaInMB={0}<br/>", dc.DiagnosticInfrastructureLogs.BufferQuotaInMB));
            sb.AppendLine(string.Format(@"DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter={0}<br/>", dc.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter));
            sb.AppendLine(string.Format(@"DiagnosticInfrastructureLogs.ScheduledTransferPeriod.TotalSeconds={0}<br/>", dc.DiagnosticInfrastructureLogs.ScheduledTransferPeriod.TotalSeconds));

            sb.AppendLine("<strong>Logs</strong><br/>");
            sb.AppendLine(string.Format(@"Logs.BufferQuotaInMB={0}<br/>", dc.Logs.BufferQuotaInMB));
            sb.AppendLine(string.Format(@"Logs.ScheduledTransferLogLevelFilter={0}<br/>", dc.Logs.ScheduledTransferLogLevelFilter));
            sb.AppendLine(string.Format(@"Logs.ScheduledTransferPeriod.TotalSeconds={0}<br/>", dc.Logs.ScheduledTransferPeriod.TotalSeconds));

            sb.AppendLine("<strong>PerformanceCounters</strong><br/>");
            sb.AppendLine(string.Format(@"PerformanceCounters.BufferQuotaInMB={0}<br/>", dc.PerformanceCounters.BufferQuotaInMB));
            sb.AppendLine(string.Format(@"PerformanceCounters.ScheduledTransferPeriod.TotalSeconds={0}<br/>", dc.PerformanceCounters.ScheduledTransferPeriod.TotalSeconds));
            int i = 1;
            foreach (var p in dc.PerformanceCounters.DataSources)
            {
                sTemp = getInfoDiagnosticMonitorPerformanceCountersDataSource(p);
                sb.AppendLine(string.Format(@"{0}. {1} <br/>", i, sTemp));
                i++;
            }

            sb.AppendLine("<strong>Directories</strong><br/>");
            sb.AppendLine(string.Format(@"Directories.BufferQuotaInMB={0}<br/>", dc.Directories.BufferQuotaInMB));
            sb.AppendLine(string.Format(@"Directories.ScheduledTransferPeriod.TotalSeconds={0}<br/>", dc.Directories.ScheduledTransferPeriod.TotalSeconds));
            sb.AppendLine("Directories.DataSources<br/>");
            i = 1;
            foreach (var d in dc.Directories.DataSources)
            {
                sTemp = getInfoDiagnosticMonitorDirDataSource(d);
                sb.AppendLine(string.Format(@"{0}. {1} <br/>", i, sTemp));
                i++;
            }


            sb.AppendLine("<strong>WindowsEventLog</strong><br/>");
            sb.AppendLine(string.Format(@"WindowsEventLog.BufferQuotaInMB={0}<br/>", dc.WindowsEventLog.BufferQuotaInMB));
            sb.AppendLine(string.Format(@"WindowsEventLog.ScheduledTransferLogLevelFilter={0}<br/>", dc.WindowsEventLog.ScheduledTransferLogLevelFilter));
            sb.AppendLine(string.Format(@"WindowsEventLog.ScheduledTransferPeriod.TotalSeconds={0}<br/>", dc.WindowsEventLog.ScheduledTransferPeriod.TotalSeconds));
            i = 1;
            foreach (var e in dc.WindowsEventLog.DataSources)
            {
                sTemp = e;
                sb.AppendLine(string.Format(@"{0}. {1} <br/>", i, sTemp));
                i++;
            }

            s = sb.ToString();

            return s;
        }

        public static string getInfoDiagnosticMonitorPerformanceCountersDataSource(PerformanceCounterConfiguration p)
        {
            string s = "";

            s = "CounterSpecifier=" + p.CounterSpecifier + "<br/> SampleRate.TotalSeconds=" + p.SampleRate.TotalSeconds.ToString();

            return s;
        }

        public static string getInfoDiagnosticMonitorDirDataSource(DirectoryConfiguration dc)
        {
            string s = "";

            s = "path=" + dc.Path + "<br/> container=" + dc.Container + "<br/> DirectoryQuotaInMB=" + dc.DirectoryQuotaInMB;

            return s;
        }



    }
}
